package ui;

import infrastructure.exceptions.PrivilidgesException;
import infrastructure.exceptions.operations.OperationException;
import inftrastructure.exceptions.ClientRuntimeException;

import javax.swing.*;

import server.IAdminInterface;
import core.AdminInterface;
import server.IAdminInterface;
import core.ServerFacade;

import dal.Pet_type;

import java.awt.*;              //for layout managers and more
import java.awt.event.*;        //for action events

import java.util.Iterator;
import java.util.Vector;

public class ManagePetTypeFrame extends JDialog implements ActionListener {

	// Data members definition
	private ManagePetTypeFrame managePetTypeFrame = null;
	private Pet_type currPetType = null;
	private Iterator<Pet_type> petTypesIter = null;
	private Vector <Pet_type> petTypeVec = null;
	private ClientFrame callingFrame = null;
	private IAdminInterface adminSession = null;
		
	// Components Definition
	private Container mainCotainer = null;
	private JPanel dialogPanel = new JPanel(new GridBagLayout());
	private JPanel buttonsPanel = new JPanel(new FlowLayout());
	private JTextField petTypeNameField = new JTextField(15);
	private JLabel petTypeNameLabel = new JLabel ("Pet Type:");
	private JTextArea desctextArea = new JTextArea(5,5);
	private JLabel petTypeDescLabel = new JLabel ("Description:");
	private JButton addButton = new JButton ("Add");
	private JButton closeButton = new JButton ("Close");
	private JLabel[] labels = {petTypeNameLabel, petTypeDescLabel};
	private JScrollPane DescScrollPane = new JScrollPane(desctextArea);

	// Constructor Definition
	public ManagePetTypeFrame (ClientFrame clientFrame)
	{
		// Set the title
		super(clientFrame, "Add Pet Types");
		
		// Set reference to manageUserFrame
		managePetTypeFrame = this;
		
		// Set reference to the main program
		callingFrame = clientFrame;
		
		// Set fields and labels properties
		petTypeNameField.setFont(new Font("DialogInput", Font.PLAIN, 12));
		desctextArea.setFont(new Font("DialogInput", Font.PLAIN, 12));
		petTypeNameLabel.setFont(new Font("Dialog", Font.PLAIN, 12));
		petTypeDescLabel.setFont(new Font("Dialog", Font.PLAIN, 12));
		petTypeNameLabel.setLabelFor(petTypeNameField);
		petTypeDescLabel.setLabelFor(desctextArea);
		
		// Get the AdminInterface session from the current session
		adminSession = (AdminInterface)callingFrame.currClient.session;
		
		// get the main container of the JFrame
		mainCotainer = getContentPane();
		
		// add components to container
		addComponentsToGrid(labels, dialogPanel);
		buttonsPanel.add(closeButton);
		mainCotainer.add(dialogPanel, BorderLayout.CENTER);
		mainCotainer.add(buttonsPanel, BorderLayout.SOUTH);
		
		// Register Action Listners
		addButton.addActionListener(this);
		closeButton.addActionListener(this);

		// Retrieve pet types from DB
		initPetTypeIter();
		
		// if user press on X button
		addWindowListener(new WindowAdapter(){
			public void windowClosing (WindowEvent e)
			{
				// Update pet type list at calling frame and close the window
				callingFrame.initPetTypeCombo();
				dispose();
			}
		});
		
		// Display the window
		setLocation(400, 300);
		setResizable(false);
		pack();
		setModal(true);
		setLocationRelativeTo(null);
		setVisible(true);
	}
	
	// Methods Definition
	private void addComponentsToGrid(JLabel[] labels,  
			Container container)
	{
		/** This methods add components to grid using GridBagConstraints. */

		int index = 0;
		Insets insets = new Insets(2,2,2,2);
		GridBagConstraints labelsConstrains = new GridBagConstraints();
		GridBagConstraints textfieldsConstrains = new GridBagConstraints();
		GridBagConstraints textAreaConstrains = new GridBagConstraints();
		GridBagConstraints buttonsConstrains = new GridBagConstraints();
		
		// Set constraints for labels
		labelsConstrains.gridx = 0; // labels at the left column
		labelsConstrains.gridy = 0;
		labelsConstrains.anchor = GridBagConstraints.FIRST_LINE_START; // align label to the uperleft
		labelsConstrains.gridwidth = 1; // each label occupies 1 cell
		labelsConstrains.fill = GridBagConstraints.NONE;
		labelsConstrains.weightx = 1.0;
		labelsConstrains.weighty = 0.0;
		labelsConstrains.insets = insets;
		
		// Set constraints for text fields
		textfieldsConstrains.gridx = 1; // text fields at the second column 
		textfieldsConstrains.gridy = 0;
		textfieldsConstrains.anchor = GridBagConstraints.FIRST_LINE_START; // align text fields to the left
		textfieldsConstrains.gridwidth = 2; // text field occupies 2 cells
		textfieldsConstrains.weightx = 1.0;
		textfieldsConstrains.weighty = 0.0;
		textfieldsConstrains.insets = insets;
		textfieldsConstrains.fill = GridBagConstraints.HORIZONTAL;
		
		// Set constraints for text area
		textAreaConstrains.gridx = 1; // text fields at the second column 
		textAreaConstrains.gridy = 0;
		textAreaConstrains.anchor = GridBagConstraints.FIRST_LINE_START; // align text fields to the left
		textAreaConstrains.gridwidth = 2; // text area occupies 2 cells in width
		textAreaConstrains.gridheight = 2; // text area occupies 2 cells in height
		textAreaConstrains.weightx = 1.0;
		textAreaConstrains.weighty = 1.0;
		textAreaConstrains.insets = insets;
		textAreaConstrains.fill = GridBagConstraints.BOTH;
		
		// Set constraints for buttons
		buttonsConstrains.gridx = 3; // button at the fourth  column 
		buttonsConstrains.gridy = 0; // button starts at the first row
		buttonsConstrains.anchor = GridBagConstraints.CENTER; // align button to center
		buttonsConstrains.gridwidth = 1; // button occupies 1 cells in width
		buttonsConstrains.gridheight = 3; // button occupies 2 cells in height
		buttonsConstrains.weightx = 1.0;
		buttonsConstrains.insets = insets;
		buttonsConstrains.fill = GridBagConstraints.BOTH;
		
		// Add components to container
		container.add(labels[index], labelsConstrains);
		container.add(petTypeNameField, textfieldsConstrains);
		
		index++;
		labelsConstrains.gridy++;
		textAreaConstrains.gridy = textfieldsConstrains.gridy + 1;
		container.add(labels[index], labelsConstrains);
		container.add(DescScrollPane, textAreaConstrains);
		container.add(addButton, buttonsConstrains);
	}
	
	public void actionPerformed(ActionEvent e) {
		
		int index;
		
		if (e.getSource() == addButton)
		{
			// Check if the user entered a pet type
			if (petTypeNameField.getText() == null || petTypeNameField.getText().equals(""))
			{
				JOptionPane.showMessageDialog(null, "You must enter a new Pet Type",
						"Warning", JOptionPane.WARNING_MESSAGE);
				return;
			}
			// Check that the PetType does not exits in DB
			for (index = 0; index < petTypeVec.size(); index++)
			{
				if (petTypeVec.get(index).getType_name().equals(petTypeNameField.getText()))
				{
					JOptionPane.showMessageDialog(null, "Pet Type " + petTypeNameField.getText() + " already exists!",
							"Pet Type Already Exists", JOptionPane.WARNING_MESSAGE);
					petTypeNameField.setText(null);
					petTypeNameField.requestFocusInWindow();
					return;
				}
			}
			try
			{
				// Create a pet type object and add pet type to repository
				currPetType = new Pet_type(petTypeNameField.getText(), desctextArea.getText());
				adminSession = (IAdminInterface)callingFrame.currClient.session;
				adminSession.addPetType(currPetType);
			}
			catch (OperationException ex)
			{
				JOptionPane.showMessageDialog(null, "Adding Pet Type " + petTypeNameField.getText() + " has failed" +
						"on server",
						"Error", JOptionPane.ERROR_MESSAGE);
				return;
			}
			catch(Exception ex)
			{
				throw new ClientRuntimeException(ex.getMessage(), ex);
			}	
			JOptionPane.showMessageDialog(null, "Pet Type " + petTypeNameField.getText() + " has been added",
					"Information", JOptionPane.INFORMATION_MESSAGE);
			
			// Update pet type vector and reset text fields
			petTypeVec.add(currPetType);
			petTypeNameField.setText(null);
			desctextArea.setText(null);
			
		}
		else // if the user presses close button
		{
			// Update pet type list at calling frame
			callingFrame.initPetTypeCombo();
			dispose();
		}
	}
	
	private void initPetTypeIter ()
	{
		/** This methods select all pet types from DB and insert the pet types
		 * names into ComboBOx. It is also saves pet types objects in a vector
		 * for further operations		 */
		
		int index;
		try
		{
			// Get pets types iterator from the client parent frame
			petTypesIter = callingFrame.currClient.session.getAllPetTypes();
			index = 0;
			
			petTypeVec = new Vector<Pet_type> ();
			
			while (petTypesIter.hasNext())
			{
				petTypeVec.add(petTypesIter.next());
			}
			
		}
		catch (PrivilidgesException ex)
		{
			JOptionPane.showMessageDialog(null, "Prirvileges Error!",
					"Error", JOptionPane.ERROR_MESSAGE);
			dispose();
		}
		catch(Exception ex)
		{
			throw new ClientRuntimeException(ex.getMessage(), ex);
		}		
	}
	
	private int init_confirm_display(String text)
	{
		/** this method initialize and display confirmation dialog */
		int choice = -1;
		try
		{
			choice = JOptionPane.showConfirmDialog(null,
					text,
	                "Deletion Confirmation",
	                JOptionPane.YES_NO_OPTION);
		}
		catch (HeadlessException e)
		{
			System.exit(10);
		}
		return choice;
	}
}
